/*
 * @lc app=leetcode.cn id=110 lang=cpp
 *
 * [110] 平衡二叉树
 *
 * https://leetcode.cn/problems/balanced-binary-tree/description/
 *
 * algorithms
 * Easy (58.04%)
 * Likes:    1476
 * Dislikes: 0
 * Total Accepted:    573.2K
 * Total Submissions: 987.5K
 * Testcase Example:  '[3,9,20,null,null,15,7]'
 *
 * 给定一个二叉树，判断它是否是高度平衡的二叉树。
 * 
 * 本题中，一棵高度平衡二叉树定义为：
 * 
 * 
 * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
 * 
 * 
 * 
 * 
 * 示例 1：
 * 
 * 
 * 输入：root = [3,9,20,null,null,15,7]
 * 输出：true
 * 
 * 
 * 示例 2：
 * 
 * 
 * 输入：root = [1,2,2,3,3,null,null,4,4]
 * 输出：false
 * 
 * 
 * 示例 3：
 * 
 * 
 * 输入：root = []
 * 输出：true
 * 
 * 
 * 
 * 
 * 提示：
 * 
 * 
 * 树中的节点数在范围 [0, 5000] 内
 * -10^4 
 * 
 * 
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int GetHeight(TreeNode* node) {
        if (node == nullptr)
            return 0;

        //统计完左、右子树的高度, 返回后根节点 + 1
        int leftHeight = GetHeight(node->left);     //左子树高度
        int rightHeight = GetHeight(node->right);   //右子树高度

        //由于要判断是否为平衡树, 使用 -1 进行标记
        if (leftHeight == -1 || rightHeight == -1)
            return -1;

        //左右子树高度差 > 1, 不是平衡树
        if (std::abs(leftHeight - rightHeight) > 1)
            return -1;

        //左右最大高度 + 1, 下面为获得本节点高度
        return (leftHeight > rightHeight) ? (leftHeight + 1) : (rightHeight + 1);
    }

    bool isBalanced(TreeNode* root) {
        if (root == nullptr)
            return true;

        //平衡二叉树: 所有节点的左右子树高度差不超过 1

        //需要使用后序遍历
        int leftHeight = GetHeight(root->left);
        int rightHeight = GetHeight(root->right);

        if (leftHeight == -1 || rightHeight == -1)
            return false;

        //判断是否平衡
        return std::abs(leftHeight - rightHeight) <= 1;
    }
};
// @lc code=end

